﻿// -----------------------------------------------------------------------
// <copyright file="IDAO.cs" company="CPUT">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace AGR.Data.Repository
{
    using System;
    using System.Linq;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq.Expressions;
    using System.Collections.ObjectModel;

    /// <summary>
    /// Interface for the Data Access Objects
    /// </summary>
    public interface IRepository<TEntity> : IDisposable where TEntity : class
    {
        [SuppressMessage("Microsoft.Design", "CA1006", Justification = "Nesting required for Linq functions to work.")]
        IQueryable<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate);

        [SuppressMessage("Microsoft.Design", "CA1006", Justification = "Nesting required for Linq functions to work.")]
        ReadOnlyCollection<TEntity> FindByReadOnly(Expression<Func<TEntity, bool>> predicate);

        TEntity FindSingleBy(Expression<Func<TEntity, bool>> predicate);

        IQueryable<TEntity> FindOrderBy(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
            IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "");

        ReadOnlyCollection<TEntity> FindOrderByReadOnly(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
            IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "");

        [SuppressMessage("Microsoft.Design", "CA1024", Justification = "GetAll method should not be a property")]
        IQueryable<TEntity> GetAll();

        [SuppressMessage("Microsoft.Design", "CA1024", Justification = "GetAll method should not be a property")]
        ReadOnlyCollection<TEntity> GetAllReadOnly();

        void Add(TEntity entity);

        void Update(TEntity entity);

        void Delete(TEntity entity);

        void DeleteBy(Expression<Func<TEntity, bool>> predicate);

        void SaveChanges();
    }
}
